import json
import re

from django.conf import settings
from django.contrib.auth import authenticate, login, logout
from django.core.mail import send_mail
from django.shortcuts import render, redirect
from django import http
# Create your views here.
from django.views import View

from users.models import User, Address
from django.contrib.auth.mixins import LoginRequiredMixin

from utils.email import generate_verify_email_url, decode_token
from utils.response_code import RET
from celery_tasks.tasks.email import send_verify_email


class RegisterView(View):
    def get(self, request):
        # 1. 判断是否登录状态
        if request.user.is_authenticated:
            # 2. 如果是登录状态, 就重定向到首页
            return redirect('/')
        else:
            # 3. 如果不是登录状态, 就显示注册页
            return render(request, 'register_vue.html')

    def post(self, request):
        # 1. 收集信息
        data = request.POST
        username = data.get('user_name')
        pwd = data.get('pwd')
        cpwd = data.get('cpwd')
        phone = data.get('phone')
        msg_code = data.get('msg_code')
        allow = data.get('allow')
        # 2. 校验参数
        # 2.1 判空
        if not all([username, pwd, cpwd, phone, msg_code, allow]):
            return http.HttpResponseForbidden('参数不全')
        # 2.2 逐项判断
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseForbidden('用户名不符合规则')
        if User.objects.filter(username=username).count():
            return http.HttpResponseForbidden('用户名已经存在')
        if not re.match(r'^\w{8,20}$', pwd):
            return http.HttpResponseForbidden('密码不符合规则')
        if pwd != cpwd:
            return http.HttpResponseForbidden('两次密码不一致')
        if not re.match(r'^1[345789]\d{9}$', phone):
            return http.HttpResponseForbidden('电话号码格式有误')
        if User.objects.filter(mobile=phone).count():
            return http.HttpResponseForbidden('电话号码已经被使用')
        # 短信验证码, 预留
        if not allow:
            return http.HttpResponseForbidden('请同意注册协议')
        # 3. 保存信息, 创建一个User对象,并保存
        User.objects.create_user(username=username, password=pwd, mobile=phone)
        # 4. 返回响应
        return redirect('http://www.taobao.com')


class CheckUsernameView(View):
    def get(self, reqeust, username):
        # 1. 获取参数
        pass
        # 2. 查询用户数量
        count = User.objects.filter(username=username).count()

        # 3. 返回结果
        return http.JsonResponse({'count': count})


class CheckPhoneView(View):
    def get(self, reqeust, phone):
        # 1. 获取参数
        pass
        # 2. 查询phone的使用数量
        count = User.objects.filter(mobile=phone).count()

        # 3. 返回结果
        return http.JsonResponse({'count': count})


class LoginUserView(View):
    def get(self, request):
        # 1. 判断是否登录状态
        if request.user.is_authenticated:
            # 2. 如果是登录状态, 就重定向到首页
            return redirect('/')
        else:
            # 3. 如果不是登录状态, 就显示登录页
            return render(request, 'login.html')

    def post(self, request):
        # 1. 获取参数
        username = request.POST.get('username')
        password = request.POST.get('pwd')
        remember_login = request.POST.get('remembered')
        # 2. 参数判空
        if not all([username, password]):
            return http.HttpResponseForbidden('参数不全!')
        # 3. 校验参数

        # 4. 验证用户名密码
        # try:
        #     user = User.objects.get(username=username)
        # except Exception as e:
        #     user = None

        user = authenticate(request, username=username, password=password)

        # 5. 登录用户
        if user is not None:
            login(request, user)
            # Redirect to a success page.
            pass
        else:
            # Return an 'invalid login' error message.
            return http.HttpResponse('登录失败')
        # 6. 保持登录状态
        if remember_login == 'on':
            # 保持状态
            request.session.set_expiry(3600 * 24 * 7)
        else:
            # 不保持状态
            request.session.set_expiry(0)
        # 7. 重定向到首页
        # response = redirect('/')
        # 重定向到 next 指向的地址
        response = redirect(request.GET.get('next', '/'))
        response.set_cookie('username', user.username, expires=3600 * 24 * 7)
        return response


class LogoutUserView(View):
    def get(self, request):
        # 1. 使用系统的logout方法登出用户
        logout(request)
        # 2. 清理cookie
        response = redirect('/')
        response.delete_cookie('username')
        # 3. 重定向到首页
        return response


class UserCenterView(LoginRequiredMixin, View):
    def get(self, request):
        # 1. 写一个参数字典， 用来渲染模板

        # 1.1 从request.user 获取用户
        user = request.user
        context = {
            'username': user.username,
            'mobile': user.mobile,
            'email': user.email,
            # 'email': '123@123.com',
            'email_active': user.email_active,
            # 'email_active': True,

        }
        return render(request, 'user_center_info.html', context=context)


class EmailSendView(LoginRequiredMixin, View):
    def put(self, request):
        # 1, 接收参数
        data = json.loads(request.body.decode())

        email = data.get('email')

        # 2, 校验参数
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return http.JsonResponse({'code': RET.DATAERR, 'errmsg': '邮箱格式错误'})

        # 3, 发送邮件
        # 3,1 生成验证链接
        verify_email_url = generate_verify_email_url(request.user)
        # 3,2 发送
        # send_mail(subject='验证邮件', message=verify_email_url, from_email=settings.EMAIL_HOST_USER,
        #           recipient_list=[email])
        send_verify_email.delay(verify_email_url, email)

        # 4, 保存信息
        request.user.email = email
        request.user.save()

        # 5, 返回结果
        return http.JsonResponse({'code': RET.OK, 'errmsg': '发送成功!'})


class EmailActiveView(View):
    def get(self, request):
        # 1, 获取token
        token = request.GET.get('token')
        # 2, 校验参数
        if not token:
            return http.HttpResponseForbidden('token丢失了!')
        # 3, 解密token
        user = decode_token(token)

        # 4, 保存激活信息
        if not user:
            return http.HttpResponseForbidden('token失效!')

        user.email_active = True
        user.save()

        # 5, 跳转到用户中心
        return redirect('/usercenter/')


class AddressesView(LoginRequiredMixin, View):
    def get(self, request):
        user = request.user
        addresses = user.addresses.filter(is_deleted=False)

        addresses_list = []

        for address in addresses:
            d = {
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "city": address.city.name,
                "district": address.district.name,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email,
            }
            addresses_list.append(d)

        context = {
            "addresses": addresses_list,  # 10个信息
            "default_address_id": user.default_address_id,
        }
        return render(request, 'user_center_site.html', context=context)


class AddressesCreateView(LoginRequiredMixin, View):
    def post(self, request):
        """
        form_address: {
            title: '',
            receiver: '',
            province_id: '',
            city_id: '',
            district_id: '',
            place: '',
            mobile: '',
            tel: '',
            email: '',
        },
        :param request:
        :return:
        """
        # 1, 获取数据
        data = json.loads(request.body.decode())
        title = data.get('title')
        receiver = data.get('receiver')
        province_id = data.get('province_id')
        city_id = data.get('city_id')
        district_id = data.get('district_id')
        place = data.get('place')
        mobile = data.get('mobile')
        tel = data.get('tel')
        email = data.get('email')

        # 2, 校验数据
        if not all([title, receiver, province_id, city_id, district_id, place, mobile]):
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '数据不全'})

        # 3, 数据入库
        user = request.user
        address = Address(
            user=user,
            title=title,
            receiver=receiver,
            province_id=province_id,
            city_id=city_id,
            district_id=district_id,
            place=place,
            mobile=mobile,
            tel=tel,
            email=email,
        )
        address.save()

        # 4, 组织数据
        d = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email,
        }

        # 5, 返回数据

        return http.JsonResponse({'code': RET.OK, 'errmsg': '添加成功', 'address': d})


class AddressesUpdateView(LoginRequiredMixin, View):
    def put(self, request, address_id):
        data = json.loads(request.body.decode())
        title = data.get('title')
        receiver = data.get('receiver')
        province_id = data.get('province_id')
        city_id = data.get('city_id')
        district_id = data.get('district_id')
        place = data.get('place')
        mobile = data.get('mobile')
        tel = data.get('tel')
        email = data.get('email')

        # 2, 校验数据
        if not all([title, receiver, province_id, city_id, district_id, place, mobile]):
            return http.JsonResponse({'code': RET.PARAMERR, 'errmsg': '数据不全'})

        # 3, 数据入库
        address = Address.objects.get(id=address_id)
        address.title = title
        address.receiver = receiver
        address.province_id = province_id
        address.city_id = city_id
        address.district_id = district_id
        address.place = place
        address.mobile = mobile
        address.tel = tel
        address.email = email

        address.save()

        # 4, 组织数据
        d = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email,
        }

        # 5, 返回数据

        return http.JsonResponse({'code': RET.OK, 'errmsg': '添加成功', 'address': d})


class AddressesDefaultView(LoginRequiredMixin, View):
    def put(self, request, address_id):
        # 1,准备数据
        user = request.user

        # 2,校验数据
        pass

        # 3,数据处理
        user.default_address_id = address_id

        # 4,数据入库
        user.save()

        # 5,组织结果
        res = {
            'code': RET.OK,
            'errmsg': '修改成功',
        }

        # 6,返回结果
        return http.JsonResponse(res)
